﻿using System;
using System.Collections.Generic;
using InseSoft.Models.Entities;
using InseSoft.ViewModels;
using InseSoft.Views;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using Ninject;

namespace InseSoft.Tests.Unit.ViewModels
{
    [TestClass]
    public class MainViewModelTest
    {
        private readonly IKernel kernel;
        private MainViewModel instance;

        public MainViewModelTest()
        {
            kernel = TestHelper.SetupDIKernel();
        }

        [TestInitialize]
        public void TestInitialize()
        {
            instance = kernel.Get<MainViewModel>();
        }

        [TestMethod]
        public void EmpresasCanExecute()
        {
            var usuarioMock = new Mock<IUsuario>();
            var session = kernel.Get<ApplicationSession>();
            session.Usuario = usuarioMock.Object;

            var result = instance.EmpresasCommand.CanExecute(null);

            Assert.IsFalse(result);
            usuarioMock.Verify(u => u.CanAccessMenu("Empresas"), Times.Once());
        }

        [TestMethod]
        public void ClientesCanExecute()
        {
            var usuarioMock = new Mock<IUsuario>();
            var session = kernel.Get<ApplicationSession>();
            session.Usuario = usuarioMock.Object;

            var result = instance.ClientesCommand.CanExecute(null);

            Assert.IsFalse(result);
            usuarioMock.Verify(u => u.CanAccessMenu("Clientes"), Times.Once());
        }

        [TestMethod]
        public void LineasCanExecute()
        {
            var usuarioMock = new Mock<IUsuario>();
            var session = kernel.Get<ApplicationSession>();
            session.Usuario = usuarioMock.Object;

            var result = instance.LineasCommand.CanExecute(null);

            Assert.IsFalse(result);
            usuarioMock.Verify(u => u.CanAccessMenu("Líneas"), Times.Once());
        }

        [TestMethod]
        public void MaterialesCanExecute()
        {
            var usuarioMock = new Mock<IUsuario>();
            var session = kernel.Get<ApplicationSession>();
            session.Usuario = usuarioMock.Object;

            var result = instance.MaterialesCommand.CanExecute(null);

            Assert.IsFalse(result);
            usuarioMock.Verify(u => u.CanAccessMenu("Materiales"), Times.Once());
        }

        [TestMethod]
        public void TipoCambioCanExecute()
        {
            var usuarioMock = new Mock<IUsuario>();
            var session = kernel.Get<ApplicationSession>();
            session.Usuario = usuarioMock.Object;

            var result = instance.TipoCambioCommand.CanExecute(null);

            Assert.IsFalse(result);
            usuarioMock.Verify(u => u.CanAccessMenu("Tipo de cambio"), Times.Once());
        }

        [TestMethod]
        public void CotizacionCanExecute()
        {
            var usuarioMock = new Mock<IUsuario>();
            var session = kernel.Get<ApplicationSession>();
            session.Usuario = usuarioMock.Object;

            var result = instance.CotizacionCommand.CanExecute(null);

            Assert.IsFalse(result);
            usuarioMock.Verify(u => u.CanAccessMenu("Cotizar"), Times.Once());
        }

        [TestMethod]
        public void LoginExecute()
        {
            instance.LoginCommand.Execute(null);

            Assert.IsTrue(instance.LoginViewModel.IsNotLoggedIn);
        }

        [TestMethod]
        public void EmpresasExecute_LauncherExecuted()
        {
            var launcherMock = Mock.Get(instance.WindowLauncher);
            
            instance.EmpresasCommand.Execute(null);
            
            launcherMock.Verify(l => l.Show(AppView.Empresas));
        }

        [TestMethod]
        public void ClientesExecute_LauncherExecuted()
        {
            var launcherMock = Mock.Get(instance.WindowLauncher);

            instance.ClientesCommand.Execute(null);

            launcherMock.Verify(l => l.Show(AppView.Clientes));
        }

        [TestMethod]
        public void LineasExecute_LauncherExecuted()
        {
            var launcherMock = Mock.Get(instance.WindowLauncher);

            instance.LineasCommand.Execute(null);

            launcherMock.Verify(l => l.Show(AppView.Lineas));
        }

        [TestMethod]
        public void MaterialesExecute_LauncherExecuted()
        {
            var launcherMock = Mock.Get(instance.WindowLauncher);

            instance.MaterialesCommand.Execute(null);

            launcherMock.Verify(l => l.Show(AppView.Materiales));
        }

        [TestMethod]
        public void TipoCambioExecute_LauncherExecuted()
        {
            var launcherMock = Mock.Get(instance.WindowLauncher);

            instance.TipoCambioCommand.Execute(null);

            launcherMock.Verify(l => l.Show(AppView.TipoCambio));
        }

        [TestMethod]
        public void CotizacionExecute_LauncherExecuted()
        {
            var launcherMock = Mock.Get(instance.WindowLauncher);

            instance.CotizacionCommand.Execute(null);

            launcherMock.Verify(l => l.Show(AppView.Cotizacion));
        }

        [TestMethod]
        [ExpectedException(typeof(NullReferenceException))]
        public void ExitExecute_ExceptionThrown()
        {
            instance.ExitCommand.Execute(null);
        }
    }
}
